#include "xutils.h"
#include <mutex>
#include <fstream>
#include "../lib/path.h"
using std::mutex;
using std::lock_guard;

std::vector<std::string> XUtils::split(const std::string& str, const std::string& sep)
{
	if (str.size() == 0)
	{
		return std::vector<std::string>();
	}

	std::vector<std::string> ret;
	for (std::string::size_type startPos = 0U; startPos <= str.size();)
	{
		std::string::size_type endPos = str.find(sep, startPos);
		if (endPos == std::string::npos)
		{
			endPos = str.size();
		}

		if (endPos - startPos == 0)
		{
			ret.push_back("");
		}
		else
		{
			ret.push_back(str.substr(startPos, endPos - startPos));
		}

		startPos = endPos + 1;
	}

	return ret;
}

std::string XUtils::ToString(const std::set<std::string>& setStr)
{
	std::string res;
	res.append("(");
	
	bool bEmpty = true;
	for (auto&& str : setStr)
	{
		if (!bEmpty)
		{
			res.append(", ");
		}
		bEmpty = false;
		res.append(str);
	}
	res.append(")");
	return res;
}

std::string XUtils::ToString(const std::vector<std::string>& lstStr, bool format)
{
	std::string res;

	if (format)
	{
		res.append("[");
	}

	bool bEmpty = true;
	for (auto&& str : lstStr)
	{
		if (!bEmpty)
		{
			res.append("|");
		}
		bEmpty = false;
		res.append(str);
	}

	if (format)
	{
		res.append("]");
	}
	return res;
}

bool XUtils::IsFile_H(const string& filename)
{
	return filename.ends_with(".h") || filename.ends_with(".hpp");
}

mutex mutexWriteLine;
void XUtils::WriteLine(const string& filename, const string& content)
{
	lock_guard<mutex> guard(mutexWriteLine);

	std::ofstream stream(filename.c_str(), std::ios::out | std::ios::app);
	if (stream.is_open())
	{
		stream.write(content.c_str(), content.size());
		stream.write("\n", 1);
		stream.close();
	}
}

string XUtils::ToLower(const string& content)
{
	string res = content;
	std::transform(res.begin(), res.end(), res.begin(), ::tolower);
	return res;
}

string g_strProjectPrefix;
void XUtils::SetVsProjectPrefix(const string& path)
{
	//XLog::LogMsg("SetVsProjectPrefix({})...", path);

	//string dir = Path::getPathFromFilename(Path::simplifyPath(Path::fromNativeSeparators(path)));
	//int nLoop = 0;
	//for (; !dir.empty(); dir = Path::getPathFromFilename(dir))
	//{
	//	DEAD_LOOP_BREAK(nLoop, 1000);

	//	dir.pop_back();
	//	string dirName = Path::getDirName(dir);
	//	if (Path::fileExists(dir + "/" + dirName + ".sln"))
	//	{
	//		g_strProjectPrefix = dir;
	//		XLog::LogMsg("SetVsProjectPrefix({}) ok. VsProjectPrefix = {}", path, g_strProjectPrefix);
	//		return;
	//	}
	//}

	//XLog::LogError("SetVsProjectPrefix({}) failed!", path);
	g_strProjectPrefix = Path::fromNativeSeparators(path);
	if (g_strProjectPrefix.size() > 0 && (g_strProjectPrefix.back() == '\\' || g_strProjectPrefix.back() == '/'))
	{
		g_strProjectPrefix.pop_back();
	}
	XLog::LogMsg("SetVsProjectPrefix({}) ok.", g_strProjectPrefix);
}

string XUtils::RemoveVsProjectPrefix(const string& path)
{
	return Path::getRelativePath(path, ToLower(g_strProjectPrefix));
}
